package online.flowerinsnow.minecraft.bukkit.manhunt.manager.impl;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import online.flowerinsnow.minecraft.bukkit.manhunt.Manhunt;
import online.flowerinsnow.minecraft.bukkit.manhunt.core.PlayerTeam;
import online.flowerinsnow.minecraft.bukkit.manhunt.manager.ITeamManager;
import online.flowerinsnow.minecraft.bukkit.manhunt.util.CompassUtils;
import online.flowerinsnow.minecraft.bukkit.manhunt.util.StateUtils;

import java.util.HashSet;
import java.util.Set;

public class TeamManagerImpl implements ITeamManager {
    private final Set<Player> runners = new HashSet<>();
    private final Set<Player> hunters = new HashSet<>();
    private final Set<Player> spectator = new HashSet<>();

    @Override
    public Set<Player> getRunners() {
        return runners;
    }

    @Override
    public Set<Player> getHunters() {
        return hunters;
    }

    @Override
    public Set<Player> getSpectator() {
        return spectator;
    }

    @Override
    public PlayerTeam getPlayerTeam(Player player) {
        return isRunner(player) ? PlayerTeam.RUNNER : isHunter(player) ? PlayerTeam.HUNTER : isSpectator(player) ? PlayerTeam.SPECTATOR : null;
    }

    @Override
    public boolean isRunner(Player player) {
        return runners.contains(player);
    }

    @Override
    public boolean isHunter(Player player) {
        return hunters.contains(player);
    }

    @Override
    public boolean isSpectator(Player player) {
        return spectator.contains(player);
    }

    @Override
    public void setPlayerTeam(Player player, PlayerTeam team) {
        if (team == getPlayerTeam(player)) return;
        StateUtils.clearInventory(player);
        if (team == null) {
            runners.remove(player);
            hunters.remove(player);
            spectator.remove(player);
            //noinspection ConstantConditions
            player.teleport(Bukkit.getWorld("world").getSpawnLocation());
            updateState();
            return;
        }
        switch (team) {
            case RUNNER -> {
                hunters.remove(player);
                spectator.remove(player);
                runners.add(player);
                player.setAllowFlight(false);
                player.setCollidable(true);
            }
            case HUNTER -> {
                runners.remove(player);
                spectator.remove(player);
                hunters.add(player);
                player.setAllowFlight(false);
                player.setCollidable(true);
                player.getInventory().addItem(new ItemStack(Material.COMPASS));
            }
            case SPECTATOR -> {
                runners.remove(player);
                hunters.remove(player);
                spectator.add(player);
                player.setAllowFlight(true);
                player.setCollidable(false);
                player.getInventory().addItem(CompassUtils.val_9_a);
            }
        }
        updateState();
    }

    @Override
    public void updateState() {
        Bukkit.getOnlinePlayers().forEach(p -> {
            Manhunt.getScoreboardManager().getPlayerScoreboard(p).setTeamInfo();
            if (isSpectator(p)) {
                Bukkit.getOnlinePlayers().forEach(p1 -> {
                    if (p == p1) return;
                    if (isSpectator(p1)) {
                        p1.showPlayer(Manhunt.getInstance(), p);
                    } else {
                        p1.hidePlayer(Manhunt.getInstance(), p);
                    }
                });
            } else {
                Bukkit.getOnlinePlayers().forEach(p1 -> {
                    if (p != p1) p1.showPlayer(Manhunt.getInstance(), p);
                });
            }
        });
    }
}
